﻿using System;
using NUnit.Framework;
using Nydus.Model.Entities;

namespace Nydus.Model.Repositories.Tests
{
    [TestFixture]
    class TestConcurrency
    {
        private UnitOfWork uow1 = null;
        private CustomerRepository customerRepository1 = null;

        private UnitOfWork uow2 = null;
        private CustomerRepository customerRepository2 = null;

        [SetUp]
        public void SetUp()
        {
            uow1 = new UnitOfWork();
            customerRepository1 = new CustomerRepository(uow1);

            uow2 = new UnitOfWork();
            customerRepository2 = new CustomerRepository(uow2);
        }


        [Test]
        [ExpectedException(typeof(ConcurrencyException))]
        public void Update_ConcurrentCustomerUpdate_Exception()
        {
            // Add customer to the repository
            Customer cust = new Customer();
            string customerName = "Concurrency test update SA";
            cust.Name = customerName;
            cust.DateFrom = DateTime.Now;
            customerRepository1.Add(cust);

            Assert.IsTrue(cust.Id == 0);
            uow1.Save();
            Assert.IsTrue(cust.Id > 0);
            int customerId = cust.Id;

            // Get the customer from the database using the first object context
            Customer cust1 = customerRepository1.GetById(customerId);

            // Get the customer from the database using the second object context
            Customer cust2 = customerRepository2.GetById(customerId);

            // Make changes in both objects and try to update -> exception is thrown
            cust1.Name = "Concurrency updated GmBH";
            cust2.Name = "Concurrency updated AB";

            uow1.Save();
            uow2.Save();
        }

        [Test]
        [ExpectedException(typeof(ConcurrencyException))]
        public void Update_ConcurrentAgentUpdate_Exception()
        {
            AgentRepository agentRepository1 = new AgentRepository(uow1);
            AgentRepository agentRepository2 = new AgentRepository(uow2);

            // Add to the repository
            Agent agent = new Agent();
            agent.FirstName = "Josef";
            agent.LastName = "Kafka";
            agent.DateFrom = DateTime.Now;
            agentRepository1.Add(agent);

            Assert.IsTrue(agent.Id == 0);
            uow1.Save();
            Assert.IsTrue(agent.Id > 0);
            int agentId = agent.Id;

            // Get from the database using the first object context
            Agent agent1 = agentRepository1.GetById(agentId);

            // Get from the database using the second object context
            Agent agent2 = agentRepository2.GetById(agentId);

            // Make changes in both objects and try to update -> exception is thrown
            agent1.LastName = "Kowalski";
            agent2.LastName = "Nowak";

            uow1.Save();
            uow2.Save();
        }
    }
}
